﻿package xde2d.utils
{
    import flash.geom.Matrix3D;
    import flash.geom.Vector3D;
    
    import away3d.core.math.Quaternion;

    public class Vector3DUtils extends Object
    {
        public static const TEMP_VEC3D:Vector3D = new Vector3D();
        public static const ZERO_VEC3D:Vector3D = new Vector3D(0, 0, 0);
        private static const MathPI:Number = 3.14159;

        public function Vector3DUtils()
        {
            return;
        }// end function

        public static function getAngle(param1:Vector3D, param2:Vector3D) : Number
        {
            return Math.acos(param1.dotProduct(param2) / (param1.length * param2.length));
        }// end function

        public static function matrix2euler(param1:Matrix3D) : Vector3D
        {
            var _loc_2:* = new Matrix3D();
            var _loc_3:* = new Vector3D();
            var _loc_4:* = Matrix3DUtils.RAW_DATA_CONTAINER;
            param1.copyRawDataTo(_loc_4);
            _loc_3.x = -Math.atan2(_loc_4[uint(6)], _loc_4[uint(10)]);
            _loc_2.appendRotation(_loc_3.x * 180 / MathPI, new Vector3D(1, 0, 0));
            _loc_2.append(param1);
            _loc_2.copyRawDataTo(_loc_4);
            var _loc_5:* = Math.sqrt(_loc_4[uint(0)] * _loc_4[uint(0)] + _loc_4[uint(1)] * _loc_4[uint(1)]);
            _loc_3.y = Math.atan2(-_loc_4[uint(2)], _loc_5);
            _loc_3.z = Math.atan2(-_loc_4[uint(4)], _loc_4[uint(5)]);
            if (Math.round(_loc_3.z / MathPI) == 1)
            {
                if (_loc_3.y > 0)
                {
                    _loc_3.y = -(_loc_3.y - MathPI);
                }
                else
                {
                    _loc_3.y = -(_loc_3.y + MathPI);
                }
                _loc_3.z = _loc_3.z - MathPI;
                if (_loc_3.x > 0)
                {
                    _loc_3.x = _loc_3.x - MathPI;
                }
                else
                {
                    _loc_3.x = _loc_3.x + MathPI;
                }
            }
            else if (Math.round(_loc_3.z / MathPI) == -1)
            {
                if (_loc_3.y > 0)
                {
                    _loc_3.y = -(_loc_3.y - MathPI);
                }
                else
                {
                    _loc_3.y = -(_loc_3.y + MathPI);
                }
                _loc_3.z = _loc_3.z + MathPI;
                if (_loc_3.x > 0)
                {
                    _loc_3.x = _loc_3.x - MathPI;
                }
                else
                {
                    _loc_3.x = _loc_3.x + MathPI;
                }
            }
            else if (Math.round(_loc_3.x / MathPI) == 1)
            {
                if (_loc_3.y > 0)
                {
                    _loc_3.y = -(_loc_3.y - MathPI);
                }
                else
                {
                    _loc_3.y = -(_loc_3.y + MathPI);
                }
                _loc_3.x = _loc_3.x - MathPI;
                if (_loc_3.z > 0)
                {
                    _loc_3.z = _loc_3.z - MathPI;
                }
                else
                {
                    _loc_3.z = _loc_3.z + MathPI;
                }
            }
            else if (Math.round(_loc_3.x / MathPI) == -1)
            {
                if (_loc_3.y > 0)
                {
                    _loc_3.y = -(_loc_3.y - MathPI);
                }
                else
                {
                    _loc_3.y = -(_loc_3.y + MathPI);
                }
                _loc_3.x = _loc_3.x + MathPI;
                if (_loc_3.z > 0)
                {
                    _loc_3.z = _loc_3.z - MathPI;
                }
                else
                {
                    _loc_3.z = _loc_3.z + MathPI;
                }
            }
            return _loc_3;
        }// end function

        public static function quaternion2euler(param1:Quaternion) : Vector3D
        {
            var _loc_2:* = new Vector3D();
            var _loc_3:* = param1.x * param1.y + param1.z * param1.w;
            if (_loc_3 > 0.499)
            {
                _loc_2.x = 2 * Math.atan2(param1.x, param1.w);
                _loc_2.y = Math.PI / 2;
                _loc_2.z = 0;
                return _loc_2;
            }
            if (_loc_3 < -0.499)
            {
                _loc_2.x = -2 * Math.atan2(param1.x, param1.w);
                _loc_2.y = (-Math.PI) / 2;
                _loc_2.z = 0;
                return _loc_2;
            }
            var _loc_4:* = param1.x * param1.x;
            var _loc_5:* = param1.y * param1.y;
            var _loc_6:* = param1.z * param1.z;
            _loc_2.x = Math.atan2(2 * param1.y * param1.w - 2 * param1.x * param1.z, 1 - 2 * _loc_5 - 2 * _loc_6);
            _loc_2.y = Math.asin(2 * _loc_3);
            _loc_2.z = Math.atan2(2 * param1.x * param1.w - 2 * param1.y * param1.z, 1 - 2 * _loc_4 - 2 * _loc_6);
            return _loc_2;
        }// end function

        public static function matrix2scale(param1:Matrix3D) : Vector3D
        {
            var _loc_2:* = new Vector3D();
            var _loc_3:* = Matrix3DUtils.RAW_DATA_CONTAINER;
            param1.copyRawDataTo(_loc_3);
            _loc_2.x = Math.sqrt(_loc_3[uint(0)] * _loc_3[uint(0)] + _loc_3[uint(1)] * _loc_3[uint(1)] + _loc_3[uint(2)] * _loc_3[uint(2)]);
            _loc_2.y = Math.sqrt(_loc_3[uint(4)] * _loc_3[uint(4)] + _loc_3[uint(5)] * _loc_3[uint(5)] + _loc_3[uint(6)] * _loc_3[uint(6)]);
            _loc_2.z = Math.sqrt(_loc_3[uint(8)] * _loc_3[uint(8)] + _loc_3[uint(9)] * _loc_3[uint(9)] + _loc_3[uint(10)] * _loc_3[uint(10)]);
            return _loc_2;
        }// end function

    }
}
